home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / giflzw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-12  |  3.0 KB  |  158 lines

  1. #include  <stdio.h>
  2. #include  "gif.h"
  3.  
  4. #define    MAX_LWZ_BITS        12
  5.  
  6. static int    fresh = NO;
  7. static int    code_size, set_code_size;
  8. static int    max_code, max_code_size;
  9. static int    firstcode, oldcode;
  10. static int    clear_code, end_code;
  11. static int    table[2][(1<< MAX_LWZ_BITS)];
  12. static int    stack[(1<<(MAX_LWZ_BITS))*2], *sp;
  13.  
  14. static unsigned char    buffer[280];
  15. static int        curbit, lastbit, done, last_byte;
  16.  
  17. static void
  18. initGetCode(void)
  19. {
  20.     curbit = 0;
  21.     lastbit = 0;
  22.     done = NO;
  23. }
  24.  
  25. static int
  26. GetCode(FILE *fd, int code_size)
  27. {
  28.     int        i, j, ret;
  29.     unsigned char    count;
  30.  
  31.     if ( (curbit+code_size) >= lastbit) {
  32.         if (done)
  33.             return -1;
  34.         buffer[0] = buffer[last_byte-2];
  35.         buffer[1] = buffer[last_byte-1];
  36.         if ((count = GetDataBlock(fd, &buffer[2])) == 0)
  37.             done = YES;
  38.         last_byte = 2 + count;
  39.         curbit = (curbit - lastbit) + 16;
  40.         lastbit = (2+count)*8 ;
  41.     }
  42.     ret = 0;
  43.     for (i = curbit, j = 0; j < code_size; ++i, ++j)
  44.         ret |= ((buffer[ i / 8 ] & (1 << (i % 8))) != 0) << j;
  45.     curbit += code_size;
  46.     return ret;
  47. }
  48.  
  49.  
  50. static int    ZeroDataBlock = NO;
  51.  
  52. int GetDataBlock(FILE *fd, unsigned char *buf)
  53. {
  54.     int count;
  55.  
  56.     if ((count = getc(fd)) == EOF)
  57.         return -1;
  58.     ZeroDataBlock = count == 0;
  59.     if ((count != 0) && (! ReadOK(fd, buf, count)))
  60.         return -1;
  61.     return count;
  62. }
  63.  
  64.  
  65. int initGifLZW(FILE *fp)
  66. {
  67.     int i;
  68.  
  69.     if ((set_code_size = getc(fp)) == EOF)
  70.         return EOF;
  71.     code_size = set_code_size+1;
  72.     clear_code = 1 << set_code_size ;
  73.     end_code = clear_code + 1;
  74.     max_code_size = 2*clear_code;
  75.     max_code = clear_code+2;
  76.     fresh = YES;
  77.     sp = stack;
  78.     initGetCode();
  79.     for (i = 0; i < clear_code; ++i) {
  80.         table[0][i] = 0;
  81.         table[1][i] = i;
  82.     }
  83.     for (; i < (1<<MAX_LWZ_BITS); ++i)
  84.         table[0][i] = table[1][0] = 0;
  85.     return 0;
  86. }
  87.  
  88. int LWZReadByte(FILE *fd)
  89. {
  90.     register int    i;
  91.     int    code, incode;
  92.  
  93.     if (fresh) {
  94.         fresh = NO;
  95.         do {
  96.             firstcode = oldcode = GetCode(fd, code_size);
  97.         } while (firstcode == clear_code);
  98.         return firstcode;
  99.     }
  100.  
  101.     if (sp > stack)
  102.         return *--sp;
  103.  
  104.     while ((code = GetCode(fd, code_size)) >= 0) {
  105.         if (code == clear_code) {
  106.             for (i = 0; i < clear_code; ++i) {
  107.                 table[0][i] = 0;
  108.                 table[1][i] = i;
  109.             }
  110.             for (; i < (1<<MAX_LWZ_BITS); ++i)
  111.                 table[0][i] = table[1][i] = 0;
  112.             code_size = set_code_size+1;
  113.             max_code_size = 2*clear_code;
  114.             max_code = clear_code+2;
  115.             sp = stack;
  116.             firstcode = oldcode = GetCode(fd, code_size);
  117.             return firstcode;
  118.         }
  119.         if (code == end_code) {
  120.             int        count;
  121.             unsigned char    buf[260];
  122.  
  123.             if (ZeroDataBlock)
  124.                 return -2;
  125.             while ((count = GetDataBlock(fd, buf)) > 0)
  126.                 ;
  127.             return -2;
  128.         }
  129.  
  130.         incode = code;
  131.         if (code >= max_code) {
  132.             *sp++ = firstcode;
  133.             code = oldcode;
  134.         }
  135.         while (code >= clear_code) {
  136.             *sp++ = table[1][code];
  137.             code = table[0][code];
  138.         }
  139.  
  140.         *sp++ = firstcode = table[1][code];
  141.  
  142.         if ((code = max_code) < (1<<MAX_LWZ_BITS)) {
  143.             table[0][code] = oldcode;
  144.             table[1][code] = firstcode;
  145.             ++max_code;
  146.             if ((max_code >= max_code_size) &&
  147.                 (max_code_size < (1<<MAX_LWZ_BITS))) {
  148.                 max_code_size *= 2;
  149.                 ++code_size;
  150.             }
  151.         }
  152.         oldcode = incode;
  153.         if (sp > stack)
  154.             return *--sp;
  155.     }
  156.     return code;
  157. }
  158.